package com.javasm.mingming.login.service.impl;

import com.javasm.mingming.common.RedisKeys;
import com.javasm.mingming.common.exception.JavasmException;
import com.javasm.mingming.common.exception.JavasmExceptionEnum;
import com.javasm.mingming.common.utils.EmailUtil;
import com.javasm.mingming.common.utils.TokenUtil;
import com.javasm.mingming.login.service.LoginService;
import com.javasm.mingming.webuser.entity.WebUser;
import com.javasm.mingming.webuser.entity.WebUserInfo;
import com.javasm.mingming.webuser.entity.WebUserLoginLog;
import com.javasm.mingming.webuser.service.WebUserInfoService;
import com.javasm.mingming.webuser.service.WebUserLoginLogService;
import com.javasm.mingming.webuser.service.WebUserService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * @author javasm
 * @version 0.1
 * @className LoginServiceImpl
 * @descriptioin:
 * @date 2025/1/6 14:48
 * @since jdk11
 */
@Service("loginService")
public class LoginServiceImpl implements LoginService {

    @Resource
    RedisTemplate<String,Object> redisTemplate;

    @Resource
    WebUserService webUserService;
    @Resource
    WebUserInfoService webUserInfoService;

    @Resource
    WebUserLoginLogService webUserLoginLogService;
    @Resource
    ThreadPoolTaskExecutor taskExecutor;
    @Resource
    EmailUtil emailUtil;
    @Override
    public WebUser doUnameLogin(String username, String password) {
        //根据用户名 密码 查询用户信息
        WebUser webUser = webUserService.getByUname(username);
        if (webUser == null){
            throw new JavasmException(JavasmExceptionEnum.UserNotExist);
        }
        //判断密码对不对
        if (!password.equals(webUser.getPassword())){
            throw new JavasmException(JavasmExceptionEnum.PasswordError);
        }
        //TODO:推荐使用线程池,暂时使用new Thread
/*        new Thread(()->{
            //增加需求,每天,每个用户,只记录1次登录信息
            //从redis中查询 当前用户,是否有登录记录
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
            String date = simpleDateFormat.format(new Date());
            String loginLogKey = String.format(RedisKeys.Login_Log_Key,date,webUser.getUid());
            Object o = redisTemplate.opsForValue().get(loginLogKey);
            if (o == null){
                //今天还没有登录过
                //登录的时候,需要一起查询 webuserinfo的内容
                //记录 登录信息
                WebUserLoginLog webUserLoginLog = new WebUserLoginLog();
                webUserLoginLog.setUid(webUser.getUid());
                webUserLoginLogService.save(webUserLoginLog);
                redisTemplate.opsForValue().set(loginLogKey,webUser.getUid(),1, TimeUnit.DAYS);
            }
        }).start();*/
        //线程池---异步任务
        taskExecutor.execute(()->{
            //增加需求,每天,每个用户,只记录1次登录信息
            //从redis中查询 当前用户,是否有登录记录
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
            String date = simpleDateFormat.format(new Date());
            String loginLogKey = String.format(RedisKeys.Login_Log_Key,date,webUser.getUid());
            Object o = redisTemplate.opsForValue().get(loginLogKey);
            if (o == null){
                //今天还没有登录过
                //登录的时候,需要一起查询 webuserinfo的内容
                //记录 登录信息
                WebUserLoginLog webUserLoginLog = new WebUserLoginLog();
                webUserLoginLog.setUid(webUser.getUid());
                webUserLoginLogService.save(webUserLoginLog);
                redisTemplate.opsForValue().set(loginLogKey,webUser.getUid(),1, TimeUnit.DAYS);
            }
        });

        return webUser;
    }

    @Override
    @Transactional
    //@Async
    public void doRegister(WebUser webUser) {
        //https://tongyi.aliyun.com/wanxiang/
        //添加 web_user表  web_user_info表
        //TODO:查询  邮箱是否已经存在
        webUserService.save(webUser);//100
        //System.out.println(webUser.getUid());
        if (webUser != null && webUser.getUserInfo()!=null){
            webUser.getUserInfo().setUid(webUser.getUid());
            //随机分配头像
            String baseUrl = "http://cd.ray-live.cn/imgs/headpic/pic_%s.jpg";
            //随机数
            //ThreadLocalRandom.current().nextInt(顾前不顾后);
            int index = ThreadLocalRandom.current().nextInt(0, 70);
            webUser.getUserInfo().setHeadPic(String.format(baseUrl,index));

            webUserInfoService.save(webUser.getUserInfo());//100

        }
        //存入Redis
        //由于往Redis中添加数据,不属于注册主流程,要放到子线程中
        WebUser newWebUser = webUser.clone();
        taskExecutor.execute(()->{
            Integer uid = newWebUser.getUid();
            //配置的是数据库添加的默认值，此时的 webUser.getUserInfo() 是没有其他默认属性的
            //想获取全部的数据，存入Reeis，需要重新查询
            WebUserInfo userInfo = webUserInfoService.getById(uid);//100
            newWebUser.setUserInfo(userInfo);
            // user:uid:18      user:uname:xiaohong
            String unameKey = String.format(RedisKeys.User_Uname,newWebUser.getUsername());
            redisTemplate.opsForValue().set(unameKey,newWebUser);//100
            String uidKey = String.format(RedisKeys.User_Uid,uid);
            redisTemplate.opsForValue().set(uidKey,newWebUser);//100
        });

    }

    @Override
    public void doLogout() {


    }

    @Override
    public WebUser queryByUid(String uid) {
        //CAP理论，性能 和 安全 互斥的
        //根据uid 查询 用户信息
        Integer id = Integer.valueOf(uid);
        WebUser webUser = webUserService.getByUid(id);
        if (webUser == null){
            throw new JavasmException(JavasmExceptionEnum.UserNotExist);
        }
        return webUser;
    }
    @Resource
    TemplateEngine templateEngine;

    @Override
    public void backPassword(String mail) {
        //import org.thymeleaf.context.Context;
        Context context = new Context();
        context.setVariable("abc","任意的文字,字符串");
        String token = TokenUtil.generateEmailToken(mail);
        context.setVariable("token",token);
        String html = templateEngine.process("back_password",context);
        emailUtil.sendMail(mail,"冥冥陪玩--密码找回",html);
    }

    @Override
    public String checkToken(String token) {
        String mail = TokenUtil.parse(token);
        //数据库查询,有没有这个用户
        WebUser webUser = webUserService.getEmail(mail);
        if (webUser == null){
            throw new JavasmException(JavasmExceptionEnum.UserNotExist);
        }
        Integer uid = webUser.getUid();
        String uidToken = TokenUtil.generateToken(uid.toString());
        return uidToken;
    }

    @Override
    public void updatePassword(String token, String password) {
        String uid = TokenUtil.parse(token);
        WebUser webUser = new WebUser();
        webUser.setUid(Integer.valueOf(uid));
        webUser.setPassword(password);
        webUserService.updateById(webUser);
    }
}
